<template>
  <div class="sf-table-container" v-loading="localLoading">
    <div class="sf-table-toolbar" v-if="showToolbar">
      <div class="left-toolbar-wrapper">
        <slot name="left-toolbar" />
      </div>
      <div class="right-toolbar-wrapper">
        <slot name="right-toolbar-before"></slot>
        <div class="toolbar-item">
          <el-tooltip content="刷新" placement="top">
            <i class="el-icon-refresh" @click="refresh(false)" />
          </el-tooltip>
        </div>
        <div class="toolbar-item">
          <el-tooltip content="全屏" placement="top">
            <i class="el-icon-full-screen" @click="fullScreen" />
          </el-tooltip>
        </div>
        <div class="toolbar-item">
          <el-dropdown trigger="click">
            <el-tooltip content="列设置" placement="top">
              <i class="el-icon-s-operation" />
            </el-tooltip>
            <el-dropdown-menu slot="dropdown">
              <div class="table-column-checkbox-wrapper">
                <div class="table-column-checkbox-header">
                  <el-checkbox
                    :indeterminate="isIndeterminate"
                    v-model="checkAll"
                    @change="handleCheckAllChange"
                    >全选</el-checkbox
                  >
                </div>
                <div class="table-column-checkbox-body">
                  <el-checkbox-group
                    v-model="checkedColumns"
                    @change="handleCheckedColumnsChange"
                  >
                    <div
                      v-for="(item, index) in columns"
                      :key="index"
                      class="table-column-checkbox-item"
                    >
                      <el-checkbox
                        :label="item.label"
                        :key="item.prop"
                      ></el-checkbox>
                    </div>
                  </el-checkbox-group>
                </div>
              </div>
            </el-dropdown-menu>
          </el-dropdown>
        </div>
        <slot name="right-toolbar-affter"></slot>
      </div>
    </div>
    <div class="sf-table-content">
      <el-table
        ref="sftable"
        :data="tableData"
        v-bind="$props"
        v-on="$listeners"
        :max-height="fitClientHeight ? localMaxHeight : maxHeight"
      >
        <slot
          v-for="name in Object.keys($slots)"
          :name="name"
          :slot="name"
        ></slot>

        <template v-for="(item, index) in tableColumns">
          <!-- <slot v-if="item.slot" :name="item.slot"></slot> -->
          <el-table-column
            v-if="!item.hide"
            :key="index"
            :fixed="item.fixed"
            :prop="item.prop"
            :label="item.label"
            :width="item.width"
            :min-width="item.minWidth"
            :show-overflow-tooltip="
              item.showOverflowTooltip != undefined
                ? item.showOverflowTooltip
                : showOverflowTooltip
            "
            :formatter="item.formatter"
          >
          </el-table-column>
        </template>
      </el-table>
      <el-pagination
        v-if="localPagination"
        @size-change="handleSizeChange"
        @current-change="handleCurrentChange"
        :current-page="currentPage"
        :page-size="pageSize"
        :page-sizes="pageSizes"
        :layout="pageLayout"
        :total="tableTotal"
      ></el-pagination>
    </div>
  </div>
</template>

<script>
import T from "element-ui/lib/table";
import TableColumn from "element-ui/lib/table-column";
import extend from "extend";
import _ from "lodash";
import elementResizeDetector from "element-resize-detector";

export default {
  components: {
    TableColumn,
  },
  props: {
    ...T.props,
    data: {
      type: [Array, Function],
      default: () => [],
    },
    columns: {
      type: Array,
      default: () => [],
    },
    // 是否默认加载数据
    isDefaultLoad: {
      type: Boolean,
      default: true,
    },
    showToolbar: {
      type: Boolean,
      default: false,
    },
    showOverflowTooltip: {
      type: Boolean,
      default: false,
    },
    fitClientHeight: {
      type: Boolean,
      default: false,
    },
    border: {
      type: Boolean,
      default: true,
    },
    // 是否展示分页，默认开启
    showPagination: {
      type: Boolean,
      default: true,
    },
    // 分页布局
    pageLayout: {
      type: String,
      default: "total, sizes, prev, pager, next, jumper",
    },
    // 分页数量的配置
    pageSizes: {
      type: Array,
      default: () => [15, 50, 100, 300, 500],
    },
    // 请求数据默认指向
    request: {
      type: Object,
      default: () => {
        return {
          pageNum: "pageNum", // 当前页指向
          pageSize: "pageSize", // 每页显示条数指向
        };
      },
    },
    // 请求返回默认的指向映射
    response: {
      type: Object,
      default: () => {
        return {
          list: "content.list", // 数据指向
          total: "content.total", // 数据总数指向
        };
      },
    },
  },

  data() {
    return {
      localLoading: false, // 表格加载状态
      tableData: [], // 表格数据
      tableTotal: 0, // 表格总数
      currentPage: 1, // 当前页，默认查询第一页
      pageSize: this.pageSizes[0] || 15, // 每页显示条数
      localPagination: this.showPagination, // 显示分页
      localMaxHeight: 400,
      sorter: {}, // 记录排序
      timer: null,
      cols: TableColumn.props,
      tableColumns: extend(true, [], this.columns),
      checkAll: true,
      isIndeterminate: false,
      checkedColumns: this.columns.map((item) => item.label),
    };
  },
  computed: {
    // tableColumns() {
    //   let slots = this.$slots.default || []
    //   slots = slots.map(item => {
    //     return item.componentOptions.propsData
    //   })
    //   console.log(slots)
    //   return slots
    // },
  },
  watch: {},
  created() {
    // if (this.isDefaultLoad) {
    //   this.loadData();
    // }
  },
  mounted() {
    // this.resizeHandler()
  },
  methods: {
    // 加载数据方法
    loadData(params, sorter) {
      // 本地静态数据
      if (Array.isArray(this.data)) {
        // 添加索引
        if (this.currentPage === 1) {
          this.data.forEach((item, index) => {
            item.__row_index = index + 1;
          });
        }
        if (this.showPagination && this.data.length) {
          this.localPagination = true;
          this.tableTotal = this.data.length;
          this.tableData = this.data.slice(
            (this.currentPage - 1) * this.pageSize,
            this.currentPage * this.pageSize
          );
        } else {
          this.localPagination = false;
          this.tableData = this.data || [];
        }
        return;
      }

      // 接口数据
      this.localLoading = true;
      this.sorter = sorter;
      let parameter = {};
      if (this.showPagination) {
        parameter = extend(
          true,
          {
            [this.request.pageNum]: this.currentPage,
            [this.request.pageSize]: this.pageSize,
          },
          params
        );
      } else {
        parameter = extend(true, {}, params);
      }

      const result = this.data(parameter);
      // 对接自己的数据接口
      if (
        (typeof result === "object" || typeof result === "function") &&
        typeof result.then === "function"
      ) {
        result
          .then((res) => {
            const list = _.get(res, this.response.list) || [];
            const total = _.get(res, this.response.total) || 0;
            console.log(res);

            // 添加索引
            list.forEach((item, index) => {
              item.__row_index =
                (this.currentPage - 1) * this.pageSize + index + 1;
            });

            // 为防止删除数据后导致页面当前页面数据长度为 0 ,自动翻页到上一页
            if (
              list.length === 0 &&
              this.showPagination &&
              this.currentPage > 1
            ) {
              this.currentPage--;
              this.loadData();
              return;
            }

            // 这里用于判断是否显示分页，当this.showPagination = true 且 list 为空时，表示数据不满足分页大小，关闭 table 分页功能
            if (this.showPagination) {
              if (list.length === 0) {
                this.localPagination = false;
              } else {
                this.localPagination = true;
              }
            }
            this.tableData = list; // 返回结果中的数组数据
            this.tableTotal = total;
          })
          .catch(() => {
            this.tableData = [];
            this.tableTotal = 0;
            this.localPagination = false;
          })
          .finally(() => {
            this.localLoading = false;
          });
      }
    },

    // 表格重新加载方法
    // 如果参数为 true, 则强制刷新到第一页
    refresh(toFirstPage = true) {
      if (toFirstPage) {
        this.currentPage = 1;
      }
      this.loadData();
    },

    // 更改分页
    handleCurrentChange(val) {
      this.currentPage = val;
      this.loadData();
    },

    // 更改每页显示条数
    handleSizeChange(val) {
      this.currentPage = 1;
      this.pageSize = val;
      this.loadData();
    },

    // 计算表格高度
    resizeHandler() {
      this.$nextTick(() => {
        if (this.fitClientHeight && this.$refs.sftable.$el) {
          const clientHeight = document.body.clientHeight;
          const clientRect = this.$refs.sftable.$el.getBoundingClientRect();
          if (clientRect && clientRect.top) {
            const top = clientRect.top;
            this.localMaxHeight = clientHeight - top - 50;
          }
        }
      });
    },

    fullScreen(el) {
      var el = this.$refs.sftable.$el;
      var rfs =
        el.requestFullScreen ||
        el.webkitRequestFullScreen ||
        el.mozRequestFullScreen ||
        el.msRequestFullScreen;
      if (rfs) {
        rfs.call(el);
        const clientHeight = document.body.clientHeight;
        this.localMaxHeight = clientHeight - 50;
      }
    },

    handleCheckAllChange(val) {
      this.checkedColumns = val ? this.columns.map((item) => item.label) : [];
      this.isIndeterminate = false;
      if (val) {
        this.tableColumns = this.tableColumns.map((item) => {
          item.hide = false;
          return item;
        });
      } else {
        this.tableColumns = this.tableColumns.map((item) => {
          item.hide = true;
          return item;
        });
      }
    },
    handleCheckedColumnsChange(value) {
      let checkedCount = value.length;
      this.checkAll = checkedCount === this.columns.length;
      this.isIndeterminate =
        checkedCount > 0 && checkedCount < this.columns.length;
      this.tableColumns = this.tableColumns.map((item) => {
        if (value.includes(item.label)) {
          item.hide = false;
        } else {
          item.hide = true;
        }
        return item;
      });
    },
  },
};
</script>
<style lang="less" scoped>
.sf-table-toolbar {
  display: flex;
  align-items: center;
  margin-bottom: 10px;
  .left-toolbar-wrapper {
    flex: 1;
  }
  .right-toolbar-wrapper {
    display: flex;
    .el-tooltip {
      font-size: 18px;
      color: #8182a5;
      margin-left: 10px;
    }
  }
}
.table-column-checkbox-wrapper {
  .table-column-checkbox-header {
    padding: 0 15px 10px;
    border-bottom: 1px solid #3a3b5e;
  }
  .table-column-checkbox-body {
    max-height: 400px;
    overflow-y: auto;
    .table-column-checkbox-item {
      padding: 5px 15px;
      &:hover {
        color: #fff;
        background-color: #32354d;
        .el-checkbox {
          color: #fff;
        }
      }
    }
  }
}
.el-pagination {
  text-align: right;
}
</style>
